package com.hyphenate.easeui.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.widget.ImageView;

import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.FutureTarget;
import com.hyphenate.easeui.R;

import java.io.File;
import java.util.concurrent.ExecutionException;

/**
 * http://mrfu.me/2016/02/27/Glide_Caching_Basics/
 * https://github.com/bumptech/glide/wiki/Configuration
 *
 * 1-------.Created by Administrator on 2016/4/12.
 * CenterCrop()是一个裁剪技术，即缩放图像让它填充到 ImageView 界限内并且侧键额外的部分。
 * ImageView 可能会完全填充，但图像可能不会完整显示。
 *
 * 2--------.fitCenter() 是裁剪技术，即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围
 * 。该图像将会完全显示，但可能不会填满整个 ImageView。
 *
 *3-------. .priority(Priority.LOW)
 * Priority.LOW
     Priority.NORMAL
    Priority.HIGH
    Priority.IMMEDIATE
     。你正在实现一个信息详情页面，有一个英雄图片在顶部，和较小的图片在底部
    。对于最好的用户体验来说，英雄图片首先需要被加载。因此，我们用 Priority.HIGH 来处理它。
    理论上说，这应该够了，但是为了让这个实例增加点趣味，我们也将底层图像分配给低优先级，
    用 .priority(Priority.LOW) 调用

 *4---------.thumbnail( 0.1f )
 * 它有更好的意义去继续显示这张 250x250 像素版本的图像在详情视图上，
 * 并且后台去加载全分辨率的图像。Glide 的 .thumbnail()
 * 方法让这一切成为可能。 在这样的情况下，这个参数是一个 float 作为其大小的倍数。
 * 你传了一个 0.1f 作为参数，Glide 将会显示原始图像的10%的大小。如果原始图像有 1000x1000 像素，
 * 那么缩略图将会有 100x100 像素。因为这个图像将会明显比 ImageView 小很多，
 * 你需要确保它的 ScaleType 的设置是正确的。
 *
 *
 * 5-------
 *
 *
 */
public class GlideUtils {

    /**
     * .with(context)。 这里的问题实际是 Glide 的功能：当你传了一个 context，
     * 例如是当前应用的 activity，Glide 将会自动停止请求当请求的 activity
     * 已经停止的时候。这整合到了应用的生命周期中通常是非常有帮助的，但是有时工作起来是困难的，
     * 如果你的 target 是独立于应用的 activity 生命周期。这里的解决方案是用 application 的 context:
     * .with(context.getApplicationContext))。当应用资深完全停止时，
     * Glide 才会杀死这个图片请求。请求记住，再说一次，如果你的请求需要在 activity 生命周期之外去做时，才用下面这样的代码：
     * @param mContext
     * @param imageUrl
     * @param imageView
     */
    private void loadImageSimpleTargetApplicationContext(Context mContext, String imageUrl, ImageView imageView) {
        Glide
                .with( mContext.getApplicationContext() ) // safer!
                .load( imageUrl)
                        .asBitmap()
                        .into( imageView );
    }
    /**
     * 然而用 float 参数来使用 .thumbnail() 是易于设置且非常有效，但它不总是有意义的。
     * 如果缩略图是要通过网络去加载相同的全分辨率的图像，则可能不会很快。
     * 所以，Glide 提供了另一个选项去加载和显示缩略图。
     * 所不同的是，第一个缩略图请求是完全独立于第二个原始请求的。该缩略图可以是不同的资源或图片 URL，你可以为其应用不同的转换，等等。
     * 提示，如果你想要更加疯狂，你可以递归并应用一个额外的缩略图请求去请求缩略图。
     * @param mContext
     * @param imageUrl
     * @param imageView
     */
    public void loadImageThumbnailRequest(Context mContext, String imageUrl, ImageView imageView) {
        // setup Glide request without the into() method
        DrawableRequestBuilder<String> thumbnailRequest = Glide
                .with( mContext )
                .load(imageUrl );

        // pass the request as a a parameter to the thumbnail request
        Glide
                .with( mContext )
                .load( imageUrl )
                .thumbnail( thumbnailRequest )
                .into( imageView );
    }
    /**
     * 通过url获取Bitmap
     * @param mContext
     * @param imageUrl
     * @param w
     * @param h
     * @return
     */
    public Bitmap Glide_getBitmap(Context mContext, String imageUrl,int w,int h){
        Bitmap myBitmap=null;
        try {
             myBitmap = Glide.with(mContext)
                    .load(imageUrl)
                    .asBitmap() //必须
                    .centerCrop()
                    .into(w, h)
                    .get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return myBitmap;
    }

    /**
     * 获取图片缓存路径
     * @param mContext
     * @param imageUrl
     * @param w
     * @param h
     * @return
     */
    public String Glidde_getLocePath(Context mContext,String imageUrl,int w,int h){
        String path="";
        FutureTarget<File> future = Glide.with(mContext)
                .load(imageUrl)
                .downloadOnly(w, h);
        try {
            File cacheFile = future.get();
             path = cacheFile.getAbsolutePath();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return path;
    }

    /***
     *
     * 加载图片
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_loadImage(Context mContext,String uri, ImageView imageView) {
        try {
            if (uri.startsWith("http://")){
                if (!uri.contains("x-oss-process")){
                    uri +=  "?x-oss-process=image/format,webp";
                } else {
                    uri +=  "/format,webp";
                }
            }
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    /***
     *
     * 加载图片重设大小
     * 当你还没有目标 view 去知道尺寸的时候，这个选项也可能是有用的。比如，如果 App 想要在闪屏界面预热缓存
     * ，它还不能测量 ImageView 的尺寸。然而，如果你知道这个图片多少大，用 override 去提供明确的尺寸。
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_loadOverrideImage(Context mContext,String uri, ImageView imageView,int w,int h) {
        try {
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                    .override(w, h)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    /***
     *
     * 加载图片
     * .skipMemoryCache(true) 去明确告诉 Glide 跳过内存缓存。这意味着 Glide 将不会把这张图片放到内存缓存中去。
     * 这里需要明白的是，这只是会影响内存缓存！Glide 将会仍然利用磁盘缓存来避免重复的网络请求。

     这也容易知道 Glide 将会默认将所有的图片资源放到内存缓存中去。因为，指明调用 .skipMemoryCache(false) 是没有必要的。

     提示：注意个事实，如果你的一个初始请求一个但是 URL 是相同的，但没有调用 .skipMemoryCache(true)
     ，然后你后来又调用了这个方法，这是这个资源将会在内存中获取缓存。当你想要去调整缓存行为时，确保你是要调用所有相同资源的时候。
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_load_skipMemoryCache(Context mContext,String uri, ImageView imageView) {
        try {
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .skipMemoryCache( true )
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * .skipMemoryCache() 方法，
     * 它需要一个枚举而不是一个简答的布尔值。
     * 如果你想要为一个请求禁用磁盘缓存。使用枚举 DiskCacheStrategy.NONE 作为参数。
     *
     * DiskCacheStrategy.NONE 什么都不缓存，就像刚讨论的那样
     DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像。在我们上面的例子中，将会只有一个 1000x1000 像素的图片
     DiskCacheStrategy.RESULT 仅仅缓存最终的图像，即，降低分辨率后的（或者是转换后的）
     DiskCacheStrategy.ALL 缓存所有版本的图像（默认行为）

     如果你有一张图片，你知道你将会经常操作处理，并做了一堆不同的版本，对其有意义的仅仅是缓存原始分辨率图片
     。因此，我们用 DiskCacheStrategy.SOURCE 去告诉 Glide 仅仅保存原始图片：
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_load_diskCacheStrategy(Context mContext,String uri, ImageView imageView) {
        try {
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .diskCacheStrategy( DiskCacheStrategy.NONE )
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 图片在这段代码片段中将不会被保存在磁盘缓存中。然而，
     * 默认的它将仍然使用内存缓存！为了把这里两者都禁用掉，两个方法一起调用：
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_load_TowNone(Context mContext,String uri, ImageView imageView) {
        try {
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .diskCacheStrategy( DiskCacheStrategy.NONE )
                    .skipMemoryCache( true )
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
//    /**
//     * 圆角图片加载
//     * @param mContext
//     * @param uri
//     * @param imageView
//     */
//    public void Glidde_loadRoudImage(Context mContext,String uri, ImageView imageView,int radius) {
//        try {
//            Glide.with(mContext).load(uri).centerCrop().crossFade()
//                    .error(R.drawable.ease_default_avatar)
//                    .placeholder(R.drawable.ease_default_avatar)
//                    .bitmapTransform(new RoundedCornersTransformation(mContext, 15, 10,
//                            RoundedCornersTransformation.CornerType.ALL))
//                    .into(imageView);
//        } catch (Exception e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//
//    }
    /**
     * 圆形图片加载
     * @param mContext
     * @param uri
     * @param imageView
     */
    public static void Glidde_loadCropCircleImage(Context mContext,String uri, ImageView imageView) {
        try {
            if (uri.startsWith("http://")){
                if (!uri.contains("x-oss-process")){
                    uri +=  "?x-oss-process=image/format,webp";
                } else {
                    uri +=  "/format,webp";
                }
            }
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                .bitmapTransform(new CropCircleTransformation(mContext))
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    public static void Glidde_loadCropCircleImage(Context mContext,int uri, ImageView imageView) {
        try {
            Glide.with(mContext).load(uri).centerCrop().crossFade()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                    .bitmapTransform(new CropCircleTransformation(mContext))
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 如果 gifUrl 是一个 git，这没什么变化。然而，不像之前那样，如果这个 gifUrl
     * 不是一个 Gif，Glide 将会把这个 load 当成失败处理。这样做的的好处是，.error()
     * 回调被调用并且错误占位符被显示，
     * 即使 gifUrl 是一个完美的图片（但不是一个 Gif）。
     *
     *
     * .asBitmap()
     * 如果你的 App 显示一个位置的网络 URL 列表，它可能遇到常规的图片或者 Gif。在某些情况下，你可能对不想系那是整个 Gif。
     * 如果你仅仅想要显示 Gif 的第一帧，你可以调用 asBitmap() 去保证其作为一个常规的图片显示，即使这个 URL 是一个 Gif。
     * @param mContext
     * @param uri
     * @param imageView
     */
    public void Glidde_loadGifImage(Context mContext,String uri, ImageView imageView) {
        try {
            Glide.with(mContext).load(uri)
                    .asGif()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 这里需要注意的是，这仅仅对于本地视频起作用。
     * 如果没有存储在该设备上的视频（如一个网络 URL 的视频）
     * ，它是不工作的！如果你想显示视频从网络 URL，去看看 VideoView。
     * @param mContext
     * @param filePath
     * @param imageView
     */
    public void Glidde_loadLocVideo(Context mContext,String filePath, ImageView imageView) {
        try {
            Glide.with(mContext).load( Uri.fromFile( new File( filePath ) ) )
                    .asGif()
                    .error(R.drawable.ease_default_avatar)
                    .placeholder(R.drawable.ease_default_avatar)
                    .into(imageView);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
/**
 * 不能使用常规的 Glide 的方法 .into()，
 * 因为我们的自定义 view 并不继承自 ImageView。
 * 因此，我们必须创建一个 ViewTarget，并用 .into() 方法：
 * 在 target 回调方法中，我们使用我们创建的方法 setImage(Drawable drawable) 在自定义 view 类中去设置图片。另外确保你注意到我们
 * 必须在 ViewTarget 的构造函数中传递我们自定义 view 作为参数：new ViewTarget<FutureStudioView, GlideDrawable>(customView)。
 */
   /*
   public class FutureStudioView extends FrameLayout {
    ImageView iv;
    TextView tv;

    public void initialize(Context context) {
        inflate( context, R.layout.custom_view_futurestudio, this );

        iv = (ImageView) findViewById( R.id.custom_view_image );
        tv = (TextView) findViewById( R.id.custom_view_text );
    }

    public FutureStudioView(Context context, AttributeSet attrs) {
        super( context, attrs );
        initialize( context );
    }

    public FutureStudioView(Context context, AttributeSet attrs, int defStyleAttr) {
        super( context, attrs, defStyleAttr );
        initialize( context );
    }

    public void setImage(Drawable drawable) {
        iv = (ImageView) findViewById( R.id.custom_view_image );

        iv.setImageDrawable( drawable );
    }
}

   private void loadImageViewTarget() {
        FutureStudioView customView = (FutureStudioView) findViewById( R.id.custom_view );

        viewTarget = new ViewTarget<FutureStudioView, GlideDrawable>( customView ) {
            @Override
            public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                this.view.setImage( resource.getCurrent() );
            }
        };

        Glide
                .with( context.getApplicationContext() ) // safer!
                .load( eatFoodyImages[2] )
                .into( viewTarget );
    }*/

}
